<template>
  <div class="v-attributr-attr-list g-bg-white g-fd-c" style="overflow:hidden">

    <div class="_list-content g-flex-1" style="overflow:auto;margin:16px;border:1px solid #E4E3E3;">
      <div
        v-for="(row,index) in tableDataFiltered"
        :key="index"
        class="_row g-flex"
        :class="{_selected:selectedRowId===row.key}"
        @click="handleSelectRow(row)" >
        <div class="_col-label" :title="row.tips">
          {{row.rowData.name}}
        </div>
        <div class="_col-value g-relative" :data-value-type="row.editType">

          <template v-if="row.editType==='input' || row.editType==='textarea'">
            <m-simple-input
              ref="input"
              v-model="row.rowData.value"
              :readonly="row.readonly"
              :class="row.readonly ? '_readonly':''"
              :type="row.editType"
              @focus="handleFocusRow($event,row)"
              @blur="handleSaveInput(row)"
            />
          </template>
          <template v-else-if="row.editType==='switch'">
            <a-checkbox :checked="row.rowData.value" :disabled="row.readonly" @change="handleCheckChange($event,row)">
              {{ row.rowData.value }}
            </a-checkbox>

          </template>
          <template v-else-if="row.editType==='single-select'">
            <a-select v-model="row.rowData.value"  style="width:164px" @change="handleSingleSelectChange($event,row)">
              <a-select-option
                v-for=" (item,index) in row.items || []"
                :key="index"
                :value="item.value"
                :title="item.label"

              >
                {{item.label}}
              </a-select-option>
            </a-select>
            <!-- <div v-for="(it,index) in row.rowData.value" :key="index">{{it.value}}</div> -->
          </template>
          <template v-else-if="row.editType==='muti-select'">
            <a-select v-model="row.rowData.value"  @change="handleMultiSelectChange($event,row)">
              <a-select-option
                v-for=" (item,index) in row.options || []"
                :key="index"
                :value="item.value"
                :title="item.label"
              >
                {{item.label}}
              </a-select-option>
            </a-select>
            <div v-for="(it,index) in row.rowData.value" :key="index">{{it.value}}</div>
          </template>
          <template v-else-if="row.editType==='tree-single-select'">

            <span v-if="row.rowData.value" class="g-inline-block" style="padding-right:14px">
              <img v-if="row.rowData.value.iconPath" style="margin-top:-3px" :src="row.rowData.value.iconPath"/>
              {{row.rowData.value.displayTitle}}
            </span>
            <span v-if="!row.readonly" class="_img-btn" style="position:absolute;top:8px;right:4px" @click="handleSingleSelect(row)">
              <img style="height:12px;width:12px" src='statics/icons/app/iconmore.png'>
            </span>

          </template>
          <template v-else-if="row.editType==='tree-muti-select'">
            <div  style="padding-right:14px">
              <div v-for="(it,index) in row.rowData.value" :key="index">
                <img v-if="it.iconPath" style="margin-top:-3px" :src="it.iconPath"/>
                <span class="g-m-lr-6">{{it.displayTitle }}</span>
                <!-- <img  v-if="!row.readonly" class="_img-btn" src="statics/icons/app/icondelete2.png" style="height:14px;width:14px"/> -->
              </div>
            </div>
            <span v-if="!row.readonly" class="_img-btn" style="position:absolute;top:8px;right:4px" @click="handleMultiSelect(row)">
              <img style="height:12px;width:12px" src='statics/icons/app/iconadd3.png' >
            </span>
          </template>
          <template v-else-if="row.editType==='compounded-input'" >
            <m-compounded-input :type="row.rowData.type " :value="row.rowData.value" :row="row" @change="handleCompoundChange($event, row)"/>

          </template>
          <template v-if="row.editType==='muti-row-input' ">
            <div style="margin:-5px 0 -5px -5px">
              <div class="g-m-r-20" style="border-right:1px solid #E4E3E3">
                <div v-for="(item,index) in row.rowData.valuex || ['1','2','3']" :key="index" class="g-relative g-flex g-flex-1" style="border-bottom:1px solid #E4E3E3">
                  <m-simple-input
                    v-model="item[index]"
                    :readonly="row.readonly"
                    :class="row.readonly ? '_readonly':''"
                    :height="'30px'"
                    style="margin-right:10px;padding-left:5px;padding-top:5px;padding-bottom:5px"
                    type="textarea"
                    @focus="handleMultiRowFocusRow($event,row,index)"
                    @blur="handleMultiRowSaveInput(row,index)"
                  />
                  <span v-if="!row.readonly" class="_img-btn" style="position:relative;top:8px;right:4px;height:16px" @click="handleMultiRowDelete(row)">
                    <img style="height:12px;width:12px" src='statics/icons/app/icondelete2.png'>
                  </span>
                </div>
              </div>
              <span v-if="!row.readonly" class="_img-btn" style="position:absolute;top:8px;right:4px" @click="handlePopMultiRowInput(row)">
                <img style="height:12px;width:12px" src='statics/icons/app/iconadd3.png'>
              </span>

            </div>

          </template>

        </div>
      </div>
    </div>

  </div>
</template>
<script>
import { debounce } from 'lodash';
import { SysMLUtilHelper } from 'src/api/sysml-imports';
import { findNodeByValue } from 'src/util/common';
import { ModelTreeDataGenerator } from "src/api/generator/model-tree-data-generator";
import { selectValue } from './../modals/SelectValue';
import { selectMutiple } from './../modals/SelectMutiple';
import { escape2Html } from "src/util/common";
import SimpleInput from './SimpleInput';
import CompoundedInput from './CompoundedInput';
import { textModal } from '../modals/TextModal';
import graphUtil from 'pages/mxgraph/graphUtil';
import {  PropertyUtil } from "components/Attribute/comps/PropertyUtil";

export default {
  name: 'comp-attr-list',
  components: {
    'm-simple-input': SimpleInput,
    'm-compounded-input': CompoundedInput
  },
  props: {
    elementId: String,
    confirmMode: String,
    mode: {
      type: String,
      default: "normal" //// detail
    }
  },
  data() {
    return {
      sortActive: false,
      showLevel: 1,
      showLevelOptions: [
				  {
          value: 1,
          label: '标准',
        },
        {
          value: 2,
          label: '专家'
        },
        {
          value: 3,
          label: '全部'
        }
      ],
      tableData: [],
      selectedRowId: undefined,
      inSelect: false,
      events: {
        'model-update': this.loadTableData
      }

    };
  },
  computed: {
    tableDataFiltered(){
      let list = this.tableData.filter(i => i.displayLevel <= this.showLevel);

      if (this.sortActive){
        list = this.sortByWord(list);
      }
      return list;
    },
    footerInfo() {
      const row = this.tableData.find(row => row.key === this.selectedRowId);
      return row ? {
        name: row.name,
        tips: row.tips

      } : {};

    },
    selectedElement(){
      console.log('get selectedElement');
      return app.selectedElement;
    }
  },
  watch: {
    selectedElement: {
      handler: function (val, oldVal) {
        this.loadTableData();
      },
      deep: false,
      immediate: true
    },
  },
  mounted(){
    this.$bus.onBatch(this.events);

  },
  beforeDestroy(){
    this.$bus.offBatch(this.events);

  },
  methods: {
    handleSort(){
      this.sortActive = !this.sortActive;
    },
    handleSetUp(){
    },
    handleSelectRow(row){
      this.selectedRowId = row.key;
    },
    loadTableData: debounce(function(){
      window.requestAnimationFrame(() => {
        console.log('load table data');
        console.time('attribute load-data');

        let selectedElement = app.selectedElement;

        if (!selectedElement) {
          this.tableData = [];
          return;
        }
        console.log(selectedElement, '-----selectedElement');
        //// this.tableData = this.getModelProperty(selectedElement);
        let tempData = this.getWizardProperty(selectedElement);
        //// 新建赋值
        tempData[0].rowData.value = 0;
        tempData[1].rowData.value = 0;
        this.tableData = tempData;
        console.timeEnd('attribute load-data');

      });

    }, 100),
    generateItemList(list){
    },
    //// 获取向导的属性
    getWizardProperty(selectedElement){
      let data = [];
      //// 通过配置文件获得模型属性的列表getStereotypeName
      const now = Date.now();
      const modelConfig = app.activeProject.configManager.getWizardConfig()['ItemFlow'];
      let connectorEdge = selectedElement;
      let sourceElement = connectorEdge.getSource().model;
      let targetElement =  connectorEdge.getTarget().model;

      //// const ItemFlowElement = modelApi.createRelationship({ typeName: 'ItemFlow', parentElement: selectedElement, sourceElement, targetElement });

      //// table数据生成
      //// 可选项目生成
      let itemList = [{ "label": "<新建>", "value": 0 }];

      let allItems = SysMLUtilHelper.getItemFlowList(selectedElement.model);
      allItems.toArray().forEach((x, index) => {
        let element = x.semanticModelBridge.elementCore.element;
        let itemLabel = '从 ' + element.informationSource.toArray()[0].name + ' 到 ' + element.informationTarget.toArray()[0].name;
        itemList.push({ "label": itemLabel, "value": index + 1 });

      });

      modelConfig.properties[0].items = itemList;
      let selectedIndex = 0;
      let DirectionList = [
        { "label": '从' + connectorEdge.getSource().name + '到' + connectorEdge.getTarget().name, "value": 0  },
        { "label": '从' + connectorEdge.getTarget().name + '到' + connectorEdge.getSource().name, "value": 1  }
      ];

      modelConfig.properties[1].items = DirectionList;
      console.log(modelConfig.properties[0], modelConfig.properties[1]);
      //// 绑定第3个对象

      //// 数据生成 事件绑定 对象写入

      if (modelConfig) {
        let modelPropertys = modelConfig.properties;
        modelPropertys.forEach((prop, index) => {
          if (prop.name === '' || prop.getMethod === '') return;
          let typeValue = null;//// 拿到属性值
          if (prop.fromStereotype) { //// 需要从stereotype获得属性值
            if (SysMLUtilHelper.isElement(selectedElement)) {
              let appliedStereotypes = selectedElement.getAppliedStereotypes();
              if (appliedStereotypes != null && appliedStereotypes.size > 0) {
                typeValue = appliedStereotypes.toArray()[0][prop.getMethod] ? appliedStereotypes.toArray()[0][prop.getMethod]() : null;
              }
            }
          } else {
            typeValue = selectedElement[prop.getMethod] ? selectedElement[prop.getMethod]() : null;
          }

          let propdata = JSON.parse(JSON.stringify(prop));
          //// valueType : value , object, valueArray, objectArray
          propdata.rowData = { name: propdata.name, value: undefined, valueType: undefined, icon: '', order: index, inEdit: false };
          //// getItems覆盖
          //// template 最少走通一条路 ,然后再拓展，新建最简单 =>应该是json
          //// 列表的动态生成

          //// editType: input textarea radio  single-select muti-select object-single-select object-muti-select
          //// allowCustom: Boolean
          //// customEditType: as same as editType
          //// filterCondition:'Package' / 'Package,Model'
          /**
           * 普通输入框：input  1
            长文本输入框：textarea 1
            富文本：rich-textarea
            开关：switch
            普通下拉单选：single-select
            普通下拉多选： muti-select
            对象树型单选：tree-single-select 1
            对象树形多选：tree-muti-select 1
            对象下拉单选：drop-single-select
            对象下拉多选：drop-muti-select
            混合输入框：compounded-input 类型切换的输入框
            多行输入框：muti-row-input
           */
          const editType = propdata.editType;
          //// valueable：true: string/number, false:Object,  collection：是否是集合
          //// 如果是string/number
          if ( editType === 'input' || editType === 'textarea' ) {
            propdata.rowData.inEdit = false;
            typeValue = escape2Html(typeValue);
            propdata.rowData.value = typeValue;
            propdata.rowData.valueEdit = typeValue;

          //// 通过反射获得属性值，并调用SysMLUtilHelper.getElementName(element)方法获得其名称
          //// 如果是对象
          } else if ( editType === 'tree-single-select' ) {
            propdata.rowData.value = typeValue;
            propdata.rowData.iconPath = this.getIconPath(ModelTreeDataGenerator.getIcon(typeValue));

          //// todo 说明属性值是一个集合，并且集合元素为非object元素 通过反射获得属性值，并循环将集合里面的值显示出来
          //// string/number 数组
          } else if ( editType === 'muti-select' ) {
            propdata.rowData.value = typeValue;

          //// 通过反射获得属性值，并循环将集合里面的object元素，分别调用SysMLUtilHelper.getDisplayText(element)方法获得其名称
          //// 对象数组
          } else if ( editType === 'tree-muti-select' ) {
            propdata.rowData.value =  this.getTypeObject(typeValue);
            //// propdata.rowData.value.forEach(val => {
            ////   val.icon = val.src;
            //// });

          //// 布尔类型属性的修改，true和false
          } else if ( editType === 'switch' ) {
            propdata.rowData.value =  typeValue;

          //// 普通下拉列表
          } else if ( editType === 'single-select' ) {
            if (typeValue && typeof typeValue !== "string") {
              propdata.rowData.value =  typeValue.toString();
            } else {
              propdata.rowData.value = typeValue;
            }

            //// propdata.rowData.value.forEach(val => {
            ////   val.icon = val.src;
            //// });

          //// 布尔类型属性的修改，true和false
          } else if (editType === 'compounded-input'){

            propdata.rowData.type =  SysMLUtilHelper.getElementClassName(typeValue) || 'LiteralString';
            if (typeValue){
              propdata.rowData.value =  SysMLUtilHelper.getDisplayText(typeValue);
            } else {
              propdata.rowData.value = "";
            }

          }
          data.push(propdata);
        });
      } else {
        console.error('找不到对应类型的配置：' + SysMLUtilHelper.getStereotypeName(selectedElement));
      }
      return data;
    },

    getTypeObject(fromData)  {

      let typeArray = [];
      for (const key in fromData) {
        if ( typeof fromData[key] === 'object' ) {
          for (let index = 0; index <  fromData[key].length; index++) {
            typeArray.push({
              name: escape2Html(SysMLUtilHelper.getDisplayText(fromData[key][index])),
              icon: this.getIconPath(ModelTreeDataGenerator.getIcon(fromData[key][index])),
              id: fromData[key][index].id
            });
          }
        }
      }
      return typeArray;
    },
    getIconPath(name){
      if (!name) return;
      return 'statics/images/sysml/' + name + '.svg';
    },
    handleSingleSelect(row){
      if (this.inSelect) return;
      this.inSelect = true;
      //// if (row.moreBtnType === 'Select Owner'){

      window.event.stopPropagation();

      selectValue.popup({
        currentId: row.rowData.value && row.rowData.value.id,
        //// filterCondtion: row.moreBtnCondition
        //// filterCondtion: row.moreBtnCondition,
        propertyKey: row.key,
        selectedElement: app.selectedElement.model,
        isNodeSelectable: node => {
          return node.tagName === 'Property';
          //// return false;
        }
      }).then(res => {
        if (res) {
          this.updateRow(row, res);
        } else {
          this.updateRow(row);
        }

      }).catch(e => {
        if (e){
          throw e;

        }

      }).finally(res => {
        this.inSelect = false;
      });

    },
    updateRow(row, value){
      //// 对于wizard ,配置表初始化，通过交互修改配置表,统一update配置表
      row.rowData.value = value;
      console.log(this.tableData, 'table update', value);

    },
    handleSaveInput(row){
      this.updateRow(row, row.rowData.value);
      row.rowData.inEdit = false;
    },
    sortByWord(arr){
      arr = [...arr];
      arr.sort((item1, item2) => {
        return item1.name.localeCompare(item2.name);
      });
      return arr;

    },
    handleMultiSelect(row){
      if (this.inSelect) return;
      this.inSelect = true;
      window.event.stopPropagation();

      selectMutiple.popup({
        currentIds: row.rowData.value ? row.rowData.value.map(i => i.id) : [],
        //// filterCondtion: row.moreBtnCondition,
        propertyKey: row.key,
        selectedElement: app.selectedElement.model,
        isNodeSelectable: node => {
          return node.getTypeName() === "Block";
          //// return false;
        }
      }).then(res => {
        this.updateRow(row, res);
      }).catch(e => {
        //// e && console.error(e);
        if (e){
          throw e;

        }
      }).finally(() => {
        this.inSelect = false;
      });

    },
    handleFocusRow(event, row){
      this.$nextTick(() => {
        event.input.select();
      });

    },
    handleCheckChange(e, row){
      console.log(e.target.checked, row);
      row.rowData.value = e.target.checked;
      this.updateRow(row, e.target.checked);

    },
    handleSingleSelectChange(value, row){
      row.rowData.value = value;
      //// this.updateRow(row, value);
      console.log('新建');
      if (row.key === 'itemList'){
        if (this.tableData[0].rowData.value > 0){
          console.log('编辑，为原有赋值');
          let selectedElement = app.selectedElement;
          let connectorEdge = selectedElement;
          let sourceElement = connectorEdge.getSource().model;
          let targetElement =  connectorEdge.getTarget().model;

          let allItems = SysMLUtilHelper.getItemFlowList(selectedElement.model).toArray();
          let currentItemFlow = allItems[this.tableData[0].rowData.value - 1];
          //// 计算编辑itemflow的方向
          if (currentItemFlow.semanticModelBridge.elementCore.element.informationSource.toArray()[0].id === sourceElement.id){
            this.tableData[1].rowData.value =  0;
          } else {
            this.tableData[1].rowData.value =  1;
          }

          //// 多选=>modearr
          let conveyedsArray = currentItemFlow.semanticModelBridge.elementCore.element.conveyed.toArray();
          //// this.tableData[2].rowData.value =  this.getTypeObject(conveyedsArray);
          if (conveyedsArray){
            this.tableData[2].rowData.value =  conveyedsArray.map(x => findNodeByValue([app.sysmlModel], x.id));
          }
          
          let property = PropertyUtil.getNodePropertyValue(currentItemFlow, "ItemProperty");
          if (property){
            const node = findNodeByValue([app.sysmlModel], property.id);
            this.tableData[3].rowData.value = node;          
          }
          console.log(this.tableData);
        } else {
          this.tableData[1].rowData.value =  0;
          this.tableData[2].rowData.value = [];
          this.tableData[3].rowData.value = 0;
        }

      }

    },
    handleMultiSelectChange(){
      this.updateRow(row, value);
    },
    handleCompoundChange(data, row){
      const { type, value } = data;
      console.log('handleCompoundChange', data);
      let newValue;
      if (type === "OpaqueExpression") {
        newValue = SysMLUtilHelper.createValueSpecificationByType(type, value.codeType, value.value);
      } else {
        newValue = SysMLUtilHelper.createValueSpecificationByType(type, value + "");
      }

      this.updateRow(row, newValue);
    },
    handleMultiRowFocusRow(event, row, index){

    },
    handleMultiRowSaveInput(row, index){

    },
    handleMultiRowDelete(row, index){

    },
    handlePopMultiRowInput(row){
      window.event.clientX;
      textModal.popup({ text: '', x: window.event.clientX, y: window.event.clientY }).then(res => {
        console.log(res);
      });

    }

  }
};
</script>
<style lang="scss" scoped>
.v-attributr-attr-list {
	._header {
		padding:4px 10px ;
    border-bottom: 1px solid #B1CEE2;
    background:linear-gradient(180deg,rgba(232,241,246,1) 0%,rgba(226,243,255,1) 100%);
	}
	._sort {
		&._sort-active {
			background: #eac266;
			border: 1px solid #c2b597;

		}
	}
	._img-btn {
		padding: 2px;
		display: inline-block;
		box-sizing: border-box;
		cursor: pointer;
		img {
			display: block;
			height: 14px;
			width: 14px;
		}
		&:hover {
			padding: 1px;
			background: #f4df99;
			border: 1px solid #c2b597;
		}
		&:active {
			padding: 1px;
			background: #eac266;
			border: 1px solid #c2b597;
		}
	}
	._row {
		line-height: 20px;
		border-bottom: 1px solid #eee;
    ._readonly{
      color: rgba(0,0,0,.45);
    }
		._col-label {
			line-height: 20px;
			flex: 0 0 96px;
			width: 96px;
			border-right: 1px solid #eee;
			color: black;
			padding: 5px;
			font-size: 12px;
		}
		._col-value {
			line-height: 20px;
			flex:1 1 100px;
			width: 100px;
			padding: 5px;
		}
		&._selected {
			._col-label {
				background: #3483b8;
				//// border-right: 1px solid #3483b8;
				color: white;
			}
      ._col-value{
        box-sizing: border-box;
        border: 1px solid #1890FF;
      }

		}
  }
  ._footer {
    font-size:12px;
    border-top: 1px solid rgba(240,240,240,1);
    height: 60px;
    ._footer-name {
      height:24px;
      line-height: 24px;
      background:rgba(246,252,255,1);
      font-weight:600;
      color:rgba(0,0,0,1);
      padding: 0 8px;
    }
    ._footer-tips {
      padding: 0 8px;
      color:rgba(68,68,68,1);
      line-height:20px;
    }
  }

}
</style>
